﻿#include "OiPCH.hpp"
#include "hasp_api.hpp"
#define _DLL_ L"hasp_windows_x64_35936.dll"

namespace Hasp_Api
{

    typedef hasp_status_t(*_hasp_login)( hasp_feature_t feature_id,
        hasp_vendor_code_t vendor_code,
        hasp_handle_t *handle );

    typedef hasp_status_t(*_hasp_logout)( hasp_handle_t handle );

    typedef hasp_status_t(*_hasp_read)( hasp_handle_t handle,
        hasp_fileid_t fileid,
        hasp_size_t offset,
        hasp_size_t length,
        void *buffer );

    typedef hasp_status_t(*_hasp_write)( hasp_handle_t handle,
        hasp_fileid_t fileid,
        hasp_size_t offset,
        hasp_size_t length,
        const void *buffer );

    typedef hasp_status_t(*_hasp_get_size)( hasp_handle_t handle,
        hasp_fileid_t fileid,
        hasp_size_t *size );

    HINSTANCE hdll = NULL;

    hasp_status_t hasp_login(hasp_feature_t feature_id, hasp_vendor_code_t vendor_code, hasp_handle_t *handle)
    {
        if(hdll == NULL)
        {
            hdll = LoadLibrary(_DLL_);

            if (hdll == NULL)
            {
                FreeLibrary(hdll);

                return LOAD_DLL_FAILED;
            }
        }

        _hasp_login proc = (_hasp_login)GetProcAddress(hdll, "hasp_login");

        if(proc == NULL)
        {
            FreeLibrary(hdll);

            return LOAD_DLL_FAILED;
        }

        return proc(feature_id, vendor_code, handle);
    }

    hasp_status_t hasp_logout(hasp_handle_t handle)
    {
        if(hdll == NULL)
        {
            hdll = LoadLibrary(_DLL_);

            if(hdll == NULL)
            {
                FreeLibrary(hdll);

                return LOAD_DLL_FAILED;
            }
        }

        _hasp_logout proc = (_hasp_logout)GetProcAddress(hdll, "hasp_logout");

        if(proc == NULL)
        {
            FreeLibrary(hdll);

            return LOAD_DLL_FAILED;
        }

        return proc(handle);
    }

    hasp_status_t hasp_read(hasp_handle_t handle, hasp_fileid_t fileid, hasp_size_t offset, hasp_size_t length, void *buffer)
    {
        if(hdll == NULL)
        {

            hdll = LoadLibrary(_DLL_);

            if(hdll == NULL)
            {
                FreeLibrary(hdll);

                return LOAD_DLL_FAILED;
            }
        }

        _hasp_read proc = (_hasp_read)GetProcAddress(hdll, "hasp_read");

        if(proc == NULL)
        {
            FreeLibrary(hdll);

            return LOAD_DLL_FAILED;
        }

        return proc(handle, fileid, offset, length, buffer);
    }

    hasp_status_t hasp_write(hasp_handle_t handle, hasp_fileid_t fileid, hasp_size_t offset, hasp_size_t length, const void *buffer)
    {
        if(hdll == NULL)
        {

            hdll = LoadLibrary(_DLL_);

            if(hdll == NULL)
            {
                FreeLibrary(hdll);

                return LOAD_DLL_FAILED;
            }
        }

        _hasp_write proc = (_hasp_write)GetProcAddress(hdll, "hasp_write");

        if(proc == NULL)
        {
            FreeLibrary(hdll);

            return LOAD_DLL_FAILED;
        }

        return proc(handle, fileid, offset, length, buffer);
    }

    hasp_status_t hasp_get_size(hasp_handle_t handle, hasp_fileid_t fileid, hasp_size_t *size)
    {
        if(hdll == NULL)
        {

            hdll = LoadLibrary(_DLL_);

            if(hdll == NULL)
            {
                FreeLibrary(hdll);

                return LOAD_DLL_FAILED;
            }
        }

        _hasp_get_size proc = (_hasp_get_size)GetProcAddress(hdll, "hasp_get_size");

        if(proc == NULL)
        {
            FreeLibrary(hdll);

            return LOAD_DLL_FAILED;
        }

        return proc(handle, fileid, size);
    }
}
